#include <atomic>
#include <chrono>
#include <memory>
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>
#define private public
#include "async_logger.h"
#undef private
#include "gtest/gtest.h"

#define UNUSED(x) (void)(x)

namespace Base {
namespace SystemLog {
using namespace std::chrono_literals;
namespace {
constexpr size_t TEST_BUFFER_SIZE = 1024 * 1024; // 1MB
constexpr size_t TEST_MESSAGE_SIZE = 128;
constexpr int TEST_MESSAGES_COUNT = 1000;
const char TEST_CHAR = 'T';
const double TEST_MB = 1024.0 * 1024.0;

class TestOutput {
public:
    ErrCode Append(const char* data, size_t len) {
        totalBytes_ += len;
        return ERR_OK;
    }
    
    size_t GetTotalBytes() const { return totalBytes_; }
    
private:
    size_t totalBytes_ = 0;
};

} // namespace

class AsyncLoggerSecurityTest : public testing::Test {
public:
    static void SetUpTestCase(void) {}
    static void TearDownTestCase(void) {}
    void SetUp() override {
        testOutput_ = std::make_shared<TestOutput>();
        auto task = [this](const char* data, size_t len) -> ErrCode {
            return testOutput_->Append(data, len);
        };
        logger_ = std::make_unique<AsyncLogger<TEST_BUFFER_SIZE>>(task);
    }
    
    void TearDown() override {
        if (logger_ && logger_->running_.load()) {
            logger_->Stop();
        }
        logger_.reset();
        testOutput_.reset();
    }

protected:
    std::unique_ptr<AsyncLogger<TEST_BUFFER_SIZE>> logger_;
    std::shared_ptr<TestOutput> testOutput_;
};

/**
 * @tc.name: AsyncLoggerSecurityTest_001
 * @tc.desc: memory leak detection
 * @tc.type: SECURITY
 */
TEST_F(AsyncLoggerSecurityTest, AsyncLoggerSecurityTest_001)
{
    {
        testOutput_ = std::make_shared<TestOutput>();
        logger_->Start();
        const std::string msg(TEST_MESSAGE_SIZE, TEST_CHAR);
        for (int i = 0; i < TEST_MESSAGES_COUNT; ++i) {
            logger_->Append(msg.c_str(), msg.size());
        }
        logger_->Stop();
    }
}

/**
 * @tc.name: AsyncLoggerSecurityTest_002
 * @tc.desc: crash recovery testing
 * @tc.type: SECURITY
 */
TEST_F(AsyncLoggerSecurityTest, AsyncLoggerSecurityTest_002) {
    auto task = [](const char* _data, size_t _len) -> ErrCode {
        UNUSED(_data);
        UNUSED(_len);
        if (rand() % 100 == 0) {
            throw std::runtime_error("Simulated backend failure");
        }
        return ERR_OK;
    };
    auto logger = std::make_unique<AsyncLogger<TEST_BUFFER_SIZE>>(task);
    logger->Start();
    
    const std::string msg(TEST_MESSAGE_SIZE, TEST_CHAR);
    for (int i = 0; i < TEST_MESSAGES_COUNT; ++i) {
        logger_->Append(msg.c_str(), msg.size());
    }
    
    // 确保系统没有崩溃
    logger_->Flush();
    logger_->Stop();
    EXPECT_TRUE(true);
}

} // namespace SystemLog
} // namespace Base
